package org.marsdonne.auth.wechat;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.marsdonne.auth.BindRequest;
import org.marsdonne.commons.wechat.AppSecret;
import org.marsdonne.commons.wechat.AppSecretProps;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Map;

@Component
@EnableConfigurationProperties(AppSecretProps.class)
public class WechatAuthApiImpl implements WechatAuthApi {

    @Resource
    private AppSecretProps appSecrets;

    @Resource
    private ObjectMapper objectMapper;

    @Resource
    private RestTemplate restTemplate;

    public Map code2session(BindRequest bindRequest) {
        String client = bindRequest.getClient().name();
        AppSecret appSecret = this.appSecrets.getAppSecrets().get(client);
        String jsCode = bindRequest.getCustomized().get("wx_login_code").toString();

        ResponseEntity<String> responseEntity = restTemplate.getForEntity(API_CODE2SESSION_URL, String.class, appSecret.getAppId(), appSecret.getSecret(), jsCode);

        return convert(responseEntity);
    }

    @Override
    public Map getUserInfo(String token, String openid) {
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(API_USER_INFO_URL, String.class, token, openid);

        return convert(responseEntity);
    }

    @Override
    public byte[] getQrCode(QrCodeRequest request) {
        JsonNode params = objectMapper.convertValue(request.toMap(), JsonNode.class);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> body = new HttpEntity(params, headers);
        ResponseEntity<byte[]> responseEntity = restTemplate.postForEntity(API_GET_WXA_CODE_URL, body, byte[].class, request.getToken());
        return responseEntity.getBody();
    }

    private Map convert(ResponseEntity<String> responseEntity) {
        Map resp = null;

        try {
            resp = this.objectMapper.readValue(responseEntity.getBody(), Map.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return resp;
    }
}
